{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Isi Penting Generator: Article Style"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Generate a long text output with the style of an article when given important facts (isi penting in Malay)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-info\">\n",
    "\n",
    "This tutorial is available as an IPython notebook at [Malaya/example/isi-penting-generator-article-style](https://github.com/huseinzol05/Malaya/tree/master/example/isi-penting-generator-article-style).\n",
    "    \n",
    "</div>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-warning\">\n",
    "\n",
    "The results you see here are generated using stochastic methods. Learn more about the stochastic process on <a href=\"https://en.wikipedia.org/wiki/Stochastic_process\" target=\"_blank\">Wikipedia</a>\n",
    "    \n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CPU times: user 3.35 s, sys: 302 ms, total: 3.65 s\n",
      "Wall time: 3.6 s\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "/home/maguswyvern/PythonVenvs/dev-malaya/lib/python3.10/site-packages/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3397\n",
      "  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))\n",
      "/home/maguswyvern/PythonVenvs/dev-malaya/lib/python3.10/site-packages/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3927\n",
      "  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))\n"
     ]
    }
   ],
   "source": [
    "%%time\n",
    "import malaya\n",
    "from pprint import pprint"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### List all available HuggingFace transformers"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `malaya` library has a built in function to find all available transformers for this task. As of writing we have two transformers which are:\n",
    "\n",
    "1. mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased <br>\n",
    "https://huggingface.co/mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased\n",
    "   \n",
    "2. mesolitica/finetune-isi-penting-generator-t5-small-standard-bahasa-cased <br>\n",
    "https://huggingface.co/mesolitica/finetune-isi-penting-generator-t5-small-standard-bahasa-cased"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'mesolitica/finetune-isi-penting-generator-t5-small-standard-bahasa-cased': {'Size (MB)': 242,\n",
       "  'ROUGE-1': 0.24620333,\n",
       "  'ROUGE-2': 0.05896076,\n",
       "  'ROUGE-L': 0.15158954,\n",
       "  'Suggested length': 1024},\n",
       " 'mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased': {'Size (MB)': 892,\n",
       "  'ROUGE-1': 0.24620333,\n",
       "  'ROUGE-2': 0.05896076,\n",
       "  'ROUGE-L': 0.15158954,\n",
       "  'Suggested length': 1024}}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "malaya.generator.isi_penting.available_huggingface"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Load HuggingFace\n",
    "\n",
    "The Generator transformer in `malaya` is quite unique, most of the text generative model we found on the internet like GPT2 or Markov simply just continue the prefix input from user, but not for our Generator transformer. \n",
    "\n",
    "We want to generate an article or karangan like high school when the users give 'isi penting' or important facts for the article."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "def huggingface(\n",
    "    model: str = 'mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased',\n",
    "    force_check: bool = True,\n",
    "    **kwargs,\n",
    "):\n",
    "    \"\"\"\n",
    "    Load HuggingFace model to generate text based on isi penting.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    model: str, optional (default='mesolitica/finetune-isi-penting-generator-t5-base-standard-bahasa-cased')\n",
    "        Check available models at `malaya.generator.isi_penting.available_huggingface`.\n",
    "    force_check: bool, optional (default=True)\n",
    "        Force check model one of malaya model.\n",
    "        Set to False if you have your own huggingface model.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    result: malaya.torch_model.huggingface.IsiPentingGenerator\n",
    "    \"\"\"\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "You are using the default legacy behaviour of the <class 'transformers.models.t5.tokenization_t5.T5Tokenizer'>. This is expected, and simply means that the `legacy` (previous) behavior will be used so nothing changes for you. If you want to use the new behaviour, set `legacy=False`. This should only be set if you understand what it means, and thoroughly read the reason why this was added as explained in https://github.com/huggingface/transformers/pull/24565\n"
     ]
    }
   ],
   "source": [
    "model = malaya.generator.isi_penting.huggingface()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is the `generate` function and the parameters it expects. "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```python\n",
    "def generate(\n",
    "    self,\n",
    "    strings: List[str],\n",
    "    mode: str = 'surat-khabar',\n",
    "    **kwargs,\n",
    "):\n",
    "    \"\"\"\n",
    "    generate a long text given a isi penting.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    strings : List[str]\n",
    "    mode: str, optional (default='surat-khabar')\n",
    "        Mode supported. Allowed values:\n",
    "\n",
    "        * ``'surat-khabar'`` - news style writing.\n",
    "        * ``'tajuk-surat-khabar'`` - headline news style writing.\n",
    "        * ``'artikel'`` - article style writing.\n",
    "        * ``'penerangan-produk'`` - product description style writing.\n",
    "        * ``'karangan'`` - karangan sekolah style writing.\n",
    "\n",
    "    **kwargs: vector arguments pass to huggingface `generate` method.\n",
    "        Read more at https://huggingface.co/docs/transformers/main_classes/text_generation\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    result: List[str]\n",
    "    \"\"\"\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Benefits of HuggingFace\n",
    "\n",
    "With the `generate` method you can use Greedy, Beam, Sampling, Nucleus decoder and so much more, read more about it on the [HuggingFace Article on How to Generate](https://huggingface.co/blog/how-to-generate). And recently, HuggingFace also released a new article [Introducing Csearch](https://huggingface.co/blog/introducing-csearch)\n",
    "\n",
    "Let's give a few lines of important facts or isi penting for the model to use to generate text."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "isi_penting = ['Neelofa tetap dengan keputusan untuk berkahwin akhir tahun ini',\n",
    "              'Long Tiger sanggup membantu Neelofa',\n",
    "              'Tiba-tiba Long Tiger bergaduh dengan Husein Zolkepli']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As above, we can give any isi penting even if it does not make any sense. Now we'll use the `generate` method and pass in a few of the vector arguments mentioned in a previous linked article by HuggingFace."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Dia berkahwin dengan Husein Zolkepli pada tahun 2003. Dengan hubungan ini, '\n",
      " 'Zolkepli dan Neelofa berkahwin untuk kali kedua. Ketika Husein Zolkepli '\n",
      " 'bergaduh dengan Neelofa, kedua-duanya bergaduh. Ini adalah perkahwinan kedua '\n",
      " 'mereka. Pasangan itu berkahwin dalam perkahwinan yang sama.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'artikel',\n",
    "    do_sample=True,\n",
    "    max_length=256,\n",
    "    top_k=50, \n",
    "    top_p=0.95))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "At this point if you get the following error:\n",
    "\n",
    "<div class=\"alert alert-warning\">\n",
    "    \n",
    "FeatureNotFound: Couldn't find a tree builder with the features you requested: lxml.\n",
    "\n",
    "</div>\n",
    "\n",
    "Try installing `lxml` with `pip install lxml`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Previously we set the `top_k` parameter to `50`. A higher `top_k` value means the model considers more candidates, potentially leading to more diversity in the generated text but also increasing the computational cost.\n",
    "\n",
    "Now let's try lowering the parameter down and introduce the `penalty_alpha` argument to decrease randomness."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Neelofa adalah seorang gadis yang sangat baik, dan dia tidak mempunyai masa '\n",
      " 'untuk berkahwin. Dia mempunyai seorang anak perempuan bernama Husein '\n",
      " 'Zolkepli dan seorang anak lelaki bernama Neelofa. Neelofa dan Husein '\n",
      " 'Zolkepli mempunyai seorang anak perempuan bernama Neelofa.']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'artikel',\n",
    "    do_sample=True, \n",
    "    max_length=256, \n",
    "    penalty_alpha=0.8, top_k=4))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Try changing the `isi_penting` variable and rerun the generate method again for more results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "isi_penting = ['Astronomi (dari) adalah sains semula jadi yang mengkaji objek dan fenomena cakerawala.',\n",
    " 'Ia menggunakan matematik, fizik, dan kimia untuk menjelaskan asal usul dan evolusi mereka.',\n",
    " 'Objek yang menarik termasuk planet, bulan, bintang, nebula, galaksi, dan komet.',\n",
    " 'Fenomena yang relevan termasuk letupan supernova, ledakan sinar gamma, kusar, blazar, pulsar, dan radiasi latar belakang gelombang mikro kosmik.',\n",
    " 'Secara umum, astronomi mengkaji semua yang berasal dari luar atmosfer Bumi.',\n",
    " 'Kosmologi adalah cabang astronomi.',\n",
    " 'Ia mengkaji Alam Semesta secara keseluruhan.']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Istilah \"astrofizik\" digunakan pada abad ke-19, dengan pengembangan istilah '\n",
      " '\"astrofizik\" pada tahun 1836, kemudian untuk menggambarkan bidang di mana '\n",
      " 'pemerhatian telah dihasilkan, dengan cara yang sama sekali tidak dikenali '\n",
      " 'dalam sastera, dalam pelbagai disiplin. Astrofizik moden merangkumi banyak '\n",
      " 'disiplin; dari astronomi sederhana hingga matematik, fizik, dan kimia (dalam '\n",
      " 'disiplin saintifik hingga matematik, fizik, kimia), dan fizik (dalam bidang '\n",
      " 'fizik, fizik, dan kimia), semuanya menyumbang kepada bidang ini. Ahli '\n",
      " 'astronomi secara umum menganggap alam semesta sebagai alam semesta fizikal, '\n",
      " 'bukan alam semesta semula jadi. Terdapat \"teori\" saintifik untuk menyiasat '\n",
      " 'objek, dan, tidak semestinya, adalah bahawa setiap objek akan tetap '\n",
      " 'berhubungan dengan objek dan alam semesta. Astronomi adalah sains sains. '\n",
      " 'Banyak ahli astronomi menggunakan sains untuk mengkaji objek dan alam '\n",
      " 'semesta. Ini bukan sains, tetapi sebaliknya ahli astronomi. Bidang ini '\n",
      " 'mengkaji semua bentuk objek, dari alam semesta fizikal, hingga dunia '\n",
      " 'supernova. Pemerhatian yang berbeza dalam alam semesta ini termasuk '\n",
      " 'pemerhatian langit, astronomi bumi, astronomi langit, sejarah alam semesta, '\n",
      " 'dan astronomi astronomi. Yang paling terkenal ialah \"egon\", pemerhatian dari '\n",
      " 'alam semesta di mana sistem bintang berinteraksi dengan graviti. Bintang '\n",
      " 'yang bergerak jauh dalam graviti ini disebut komet, dan oleh itu disebut '\n",
      " 'galaksi']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'artikel',\n",
    "    do_sample=True,\n",
    "    max_length=256,\n",
    "    top_k=50, \n",
    "    top_p=0.95))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Dalam astronomi, \"astronomi\" adalah sains semula jadi. Ahli astronomi sering '\n",
      " 'mengkaji objek dan fenomena cakerawala, termasuk bintang. Astronomi mengkaji '\n",
      " 'semua perkara yang berasal dari luar atmosfer Bumi. Astronomi juga mengkaji '\n",
      " '\"kecerdasan alam semesta\" dan \"kecerdasan Bumi\". Astronomi adalah sains '\n",
      " 'semula jadi, yang mengkaji alam semesta secara keseluruhan. Ia mengkaji '\n",
      " 'semua perkara yang berasal dari luar atmosfer. Ahli astronomi mengkaji semua '\n",
      " 'perkara yang berasal dari luar atmosfer Bumi dan mengintegrasikannya dengan '\n",
      " 'fizik dan fizik. Astronomies adalah sains yang berkaitan dengan sains dan '\n",
      " 'sejarah, termasuk sains semula jadi, sains Bumi. Astronomi merangkumi sains '\n",
      " 'yang berkaitan dengan sains, sejarah, dan sains Bumi, termasuk sains Bumi, '\n",
      " 'fizik, dan kimia, dan sains Bumi. Astronomies mengkaji alam semesta dengan '\n",
      " 'pelbagai cara, termasuk alam semesta, sains Bumi, dan sains Bumi. '\n",
      " 'Astronomies juga mengkaji \"kecerdasan alam semesta\", \"kecerdasan alam '\n",
      " 'semesta\", \"kecerdasan Bumi\", \"kecerdasan alam semesta\", \"kecerdasan Bumi\", '\n",
      " '\"kecerdasan Bumi\", dan \"kecerdasan']\n"
     ]
    }
   ],
   "source": [
    "pprint(model.generate(isi_penting, mode = 'artikel',\n",
    "    do_sample=True, \n",
    "    max_length=256, \n",
    "    penalty_alpha=0.8, top_k=4))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.12"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
